package com.neuedu.service.impl;

import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neuedu.myUtil.JwtUtil;
import com.neuedu.pojo.SysUser;
import com.neuedu.mapper.SysUserMapper;
import com.neuedu.service.IRedisService;
import com.neuedu.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author liuyong
 * @since 2020-09-14
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    BCryptPasswordEncoder bCryptPasswordEncode;
    @Resource
	IRedisService redisService;

    @Override
    public String token(SysUser umsUser) throws JsonProcessingException {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
       if(StringUtils.isNotBlank(umsUser.getTelephone())){
           wrapper.eq("telephone",umsUser.getTelephone());
       }
        if(StringUtils.isNotBlank(umsUser.getMail())){
            wrapper.eq("mail",umsUser.getMail());
        }
        if(StringUtils.isNotBlank(umsUser.getUsername())){
            wrapper.eq("username",umsUser.getUsername());
        }

        SysUser one = this.getOne(wrapper);
        if(one != null){
            //验证密码（用户名存在）
            //如果密码一致，认为成功了
            if(bCryptPasswordEncode.matches(umsUser.getPassword(),one.getPassword())){

                LocalDateTime now = LocalDateTime.now();
                one.setLastLogin(now);
                //修改数据库的字段为当前时间
                updateLastLogin(one.getId(),now);
                //LocalDateTime转换为long类型，就是时间chuo

                //缓存用户登录信息到ssdb
                wirte2SSDB(one,now);


                //将用户信息生成token数据返回前端
                String token = JwtUtil.create(one);
                return token;

            }
        }
        return null;
    }


    //持久化到ssdb
    private void wirte2SSDB(SysUser one,LocalDateTime now) throws JsonProcessingException {

        Map info = new HashMap<>();
        info.put("username",one.getUsername());
        info.put("password",one.getPassword());
        info.put("id",one.getId());
        info.put("lastlogin",now.toInstant(ZoneOffset.of("+8")).toEpochMilli());//时间戳，转换为long

        ObjectMapper objectMapper = new ObjectMapper();
        String userJson = objectMapper.writeValueAsString(info);

        //保存登录状态信息,ssdb
        String key =JwtUtil.KEY+"-"+one.getUsername();
        redisService.set(key,userJson,30*60);

    }

    //更新最后登录成功的时间
    private void updateLastLogin(Integer id, LocalDateTime now) {
        SysUser umsUser = new SysUser();
        umsUser.setId(id);
        umsUser.setLastLogin(now);
        this.updateById(umsUser);
    }



    @Override
    public Object list(SysUser user) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(user.getUsername())){
            wrapper.like("username",user.getUsername());
        }
        if(user.getActive() != null){
            wrapper.eq("active",user.getActive());
        }
        if(user.getWithPage() == 1) {
            return page(new Page<>(user.getPageNo(), user.getPageSize()), wrapper);
        }else {
            return  this.list(wrapper);
        }

    }

    @Override
    public boolean add(SysUser umsUser) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(umsUser.getTelephone())){
            wrapper.eq("username",umsUser.getUsername());
        }

        if(StringUtils.isNotBlank(umsUser.getTelephone())){
            wrapper.eq("telephone",umsUser.getTelephone());
        }
        if(StringUtils.isNotBlank(umsUser.getTelephone())){
            wrapper.eq("mail",umsUser.getMail());
        }
        //前端应该校验邮箱或者电话必须有一个不为空**********

        SysUser one = this.getOne(wrapper);
        if(one == null){
            return  this.save(umsUser);
        }
        return  false;

    }

    @Override
    public boolean batchdel(Integer[] ids) {

        List<Integer> list = new ArrayList<Integer>(ids.length);
        Collections.addAll(list,ids);
        SysUser user = new SysUser();
        user.setActive(0);
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id",list);
        return this.update(user,updateWrapper);

    }

    @Override
    public boolean logout(HttpServletRequest request) {
        String token = request.getHeader("token");
        String username = JWT.decode(token).getClaim("username").asString();
        //删除key
        String key = JwtUtil.KEY+"-"+username;
        //设置有效期为0
        redisService.expire(key,0);

        return true;
    }

    @Override
    public Object getRealName(HttpServletRequest request) {
        String token = request.getHeader("token");
        Integer userId = JWT.decode(token).getClaim("id").asInt();
        SysUser user = this.getById(userId);
        return user;

    }

    // 校验邮箱地址
    public static boolean checkEmail(String email) {
        return email.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
    }
}
